/**
 * @file 定义路由匹配，渲染对应的 UI 组件
 * @author chris<wfsr@foxmail.com>
 */
import React from 'react';
import {Switch, Route} from 'react-router-dom';
import loadable from '@loadable/component';

import Authorized from './component/Authorized';
import Loading from './component/Loading';
import routes from './route.config';

import BasicLayout from './layout/BasicLayout';
import BlankLayout from './layout/BlankLayout';

import waterMark from './component/WaterMark';

/**
 * 拼接path
 *
 * @param {string} path 上级path
 * @param {string} subPath 子路由path
 * @return {string}
 */
const joinPath = (path, subPath) => (subPath
    ? subPath.startsWith('/') ? subPath : (path + (path.endsWith('/') ? '' : '/') + subPath)
    : path);

// 组建route
const renderRoute = route => {
    const {path, component, exact = true} = route;
    const Page = loadable(
        () => import(`~/page/${component}`),
        {fallback: <Loading />}
    );

    const Comp = waterMark(Page);

    function render(props) {
        return <Comp route={route} />;
    }

    return (
        <Route exact={exact} key={path} path={path} render={render} />
    );
};

/**
 * 将路由配置格式化：每个路由中的routes对象下的路由打平
 *
 * @param {Array} routes 路由配置数组
 * @param {Object=} superRoute 上级路由对象
 * @return {Array}
 */
const formatRoutes = (routes, superRoute) => {
    const {path = ''} = superRoute || {};

    return routes.reduce((newRoutes, route) => {
        const {routes: children, ...rest} = route;

        const {path: subPath = ''} = rest;
        rest.path = joinPath(path, subPath);
        if (superRoute) {
            rest.super = superRoute;
        }

        newRoutes.push(rest);

        if (children && children.length) {
            newRoutes.push(...formatRoutes(children, rest));
        }

        return newRoutes;
    }, []);
};

export default function Routes() {
    const list = formatRoutes(routes);
    const blankLayoutList = [];
    const basicLayoutList = [];
    for (const e of list) {
        if (e.layout === 'BlankLayout') {
            blankLayoutList.push(e);
        }
        else {
            basicLayoutList.push(e);
        }
    }
    const pathsBaiscLayout = basicLayoutList.map(e => e.path);

    // Layout route判断 展示
    return (
        <Switch>
            <Route exact path={pathsBaiscLayout}>
                <Authorized>
                    <BasicLayout>
                        <Switch>
                            {basicLayoutList.map(e => renderRoute(e))}
                        </Switch>
                    </BasicLayout>
                </Authorized>
            </Route>
            <Route>
                <BlankLayout>
                    <Switch>
                        {blankLayoutList.map(e => renderRoute(e))}
                    </Switch>
                </BlankLayout>
            </Route>
        </Switch>
    );
}
